package org.mybatis.jpetstore.web.actions;

import cn.webwheel.Action;
import cn.webwheel.WebParam;
import cn.webwheel.results.RedirectResult;
import cn.webwheel.results.TemplateResult;
import org.mybatis.jpetstore.domain.Account;
import org.mybatis.jpetstore.domain.Product;
import org.mybatis.jpetstore.service.AccountService;
import org.mybatis.jpetstore.service.CatalogService;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class AccountActionBean extends AbstractActionBean {

  private static final long serialVersionUID = 5499663666155758178L;

  private static final String NEW_ACCOUNT = "/WEB-INF/jsp/account/NewAccountForm.html";
  private static final String EDIT_ACCOUNT = "/WEB-INF/jsp/account/EditAccountForm.html";
  private static final String SIGNON = "/WEB-INF/jsp/account/SignonForm.html";

  private static final List<String> LANGUAGE_LIST;
  private static final List<String> CATEGORY_LIST;

  @Autowired
  private transient AccountService accountService;
  @Autowired
  private transient CatalogService catalogService;

  private Account account = new Account();
  private List<Product> myList;
  private boolean authenticated;

  static {
    List<String> langList = new ArrayList<String>();
    langList.add("english");
    langList.add("japanese");
    LANGUAGE_LIST = Collections.unmodifiableList(langList);

    List<String> catList = new ArrayList<String>();
    catList.add("FISH");
    catList.add("DOGS");
    catList.add("REPTILES");
    catList.add("CATS");
    catList.add("BIRDS");
    CATEGORY_LIST = Collections.unmodifiableList(catList);
  }

    @WebParam
    public Account getAccount() {
    return this.account;
  }

  public String getUsername() {
    return account.getUsername();
  }

//  @Validate(required=true, on={"signon", "newAccount", "editAccount"})
@WebParam
  public void setUsername(String username) {
    account.setUsername(username);
  }

  public String getPassword() {
    return account.getPassword();
  }

//  @Validate(required=true, on={"signon", "newAccount", "editAccount"})
@WebParam
  public void setPassword(String password) {
    account.setPassword(password);
  }

  public List<Product> getMyList() {
    return myList;
  }

  public void setMyList(List<Product> myList) {
    this.myList = myList;
  }

  public List<String> getLanguages() {
    return LANGUAGE_LIST;
  }

  public List<String> getCategories() {
    return CATEGORY_LIST;
  }

    @Action
  public Object newAccountForm() {
    return new TemplateResult(this, NEW_ACCOUNT);
  }

    private boolean validate() {
        if (account.getUsername().trim().isEmpty()) {
            return false;
        }
        if (account.getPassword().trim().isEmpty()) {
            return false;
        }
        if (account.getFirstName().trim().isEmpty()) {
            return false;
        }
        if (account.getLastName().trim().isEmpty()) {
            return false;
        }
        return true;
    }

    @Action
  public Object newAccount() {
        if (!validate()) {
            return newAccountForm();
        }
        accountService.insertAccount(account);
        account = accountService.getAccount(account.getUsername());
        myList = catalogService.getProductListByCategory(account.getFavouriteCategoryId());
        authenticated = true;
        return new RedirectResult("CatalogActionBean.viewMain");
    }

    @Action
  public Object editAccountForm() {
    return new TemplateResult(this, EDIT_ACCOUNT);
  }

    @Action
  public Object editAccount() {
        if (!validate()) {
            return editAccountForm();
        }
        accountService.updateAccount(account);
        account = accountService.getAccount(account.getUsername());
        myList = catalogService.getProductListByCategory(account.getFavouriteCategoryId());
        return new RedirectResult("CatalogActionBean.viewMain");
    }

    @Action
  public Object signonForm() {
    return new TemplateResult(this, SIGNON);
  }

    @Action
  public Object signon() {

    account = accountService.getAccount(getUsername(), getPassword());

    if (account == null) {
      String value = "Invalid username or password.  Signon failed.";
      setMessage(value);
      clear();
      return new TemplateResult(this, SIGNON);
    } else {
      account.setPassword(null);
      myList = catalogService.getProductListByCategory(account.getFavouriteCategoryId());
      authenticated = true;
      HttpSession s = ctx.getRequest().getSession();
      // this bean is already registered as /actions/Account.action
      s.setAttribute("accountBean", this);
        return new RedirectResult("CatalogActionBean.viewMain");
    }
  }

    @Action
  public Object signoff() {
    ctx.getRequest().getSession().invalidate();
    clear();
        return new RedirectResult("CatalogActionBean.viewMain");
  }

  public boolean isAuthenticated() {
    return authenticated && account != null && account.getUsername() != null;
  }

  public void clear() {
    account = new Account();
    myList = null;
    authenticated = false;
  }

}
